﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DispatchAssist.Model;
using DispatchAssist.BusinessLogical.BLL;
using DispatchAssist.BusinessLogical.Model;
using CarolLib.WinService;
using System.Xml;


namespace DispatchAssist.SMSAlertGenerator
{
    public class Generator : IBasicTask
    {

        #region members

        static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private CreateAlertMsgManager manager;

        #endregion

        #region Implete IBasicTask
        public void Init()
        {
            manager = new CreateAlertMsgManager();
        }

        public void Execute()
        {
            List<MeteoMsg> mtMsgList;

            //step 1.获取最新的气象报文
            try
            {
                mtMsgList = manager.GetUnCreateMeteoMsgList(Enums.MeteoMsgStatus.FinishCreateSMS, Enums.MeteoMsgStatus.CreateSMSError);
            }
            catch (Exception e)
            {
                Logger.Error("get new Meteo message for SMS Alert error", e);
                return;
            }
            Logger.InfoFormat("there is {0} new meteo Message", mtMsgList.Count);

            if (mtMsgList == null || mtMsgList.Count == 0)
            {
                return;
            }

            List<SMSAlert> alertList = new List<SMSAlert>();

            List<string> successList = new List<string>();

            List<string> failList = new List<string>();



            foreach (MeteoMsg mtMsg in mtMsgList)
            {
                //add at 2011-8-8
                if (!manager.IsEffective(mtMsg.Airport, mtMsg.WarnTime.AddHours((-1) * int.Parse(System.Configuration.ConfigurationManager.AppSettings["SMSEffecTime"])), mtMsg.WarnLevel, mtMsg.MetroMsgID))
                {
                    Logger.InfoFormat("the same level warn in 4 hours,MeteoMsgID: {0} ", mtMsg.MetroMsgID);
                    successList.Add(mtMsg.MetroMsgID.ToString());
                    continue;
                }

                if (string.IsNullOrEmpty(mtMsg.Airport))
                {
                    Logger.InfoFormat("there is no airport,MeteomsgID:{0}", mtMsg.MetroMsgID);

                    successList.Add(mtMsg.MetroMsgID.ToString());

                    continue;
                }

                Enums.AlertActionFlag actionFlags;
                try
                {
                   actionFlags =(Enums.AlertActionFlag) CommonCacheData.CacheAR.GetActionFlag(mtMsg.Airport, mtMsg.WarnLevel);
                }
                catch (Exception e)
                {
                    Logger.Error(string.Format("get action flag cache data error, airport :{0} warnlevel :{1}", mtMsg.Airport, mtMsg.WarnLevel), e);

                    failList.Add(mtMsg.MetroMsgID.ToString());

                    continue;
                }

                //该机场的报警规则中没有短信报警,则跳过
                if ((CreateAlertMsgManager.GetAlertType(actionFlags) & Enums.AlertType.SMSType) == 0)
                {
                    continue;
                }

                List<FlightInfo> flightList;
                try
                {
                    //step 2. 获取需要短信通知的航班
                    flightList = manager.GetSMSFlightInfoByMtMsg(mtMsg.Airport, mtMsg.WarnTime.AddHours(CommonCacheData.CacheET.GetSMSEarlyTime(mtMsg.Airport)), mtMsg.WarnTime.Date.AddDays(1));

                    successList.Add(mtMsg.MetroMsgID.ToString());

                }
                catch (Exception e)
                {
                    Logger.Error(string.Format("error in get flight info for Create SMSALert,MeoteID is {0}", mtMsg.MetroMsgID), e);

                    failList.Add(mtMsg.MetroMsgID.ToString());

                    continue;
                }

                //step 3.组装消息实体

                var groupList = flightList.GroupBy(f => f.GroupCode);

                foreach (var items in groupList)
                {
                    SMSAlert alertModel = new SMSAlert();

                    alertModel.MeteoMsgID = mtMsg.MetroMsgID;
                    alertModel.SeatID = new Guid(System.Configuration.ConfigurationManager.AppSettings["SMSSeatID"]);
                    alertModel.GroupCode = items.Key;
                    alertModel.FlightCount = items.Count();
                    alertModel.AlertActionFlag =(int) actionFlags;
                    alertModel.PerformActionFlag = 0;

                    alertModel.RelationFlights = GetRelationFlightXml(items.ToList());

                    alertList.Add(alertModel);
                }
            }

            //step 4. 插入短信预警信息
            try
            {
                manager.InsertSMSAlertList(alertList);

                Logger.InfoFormat(" create {0} SMS Alert INFo",alertList.Count);
            }
            catch(Exception e)
            {
                Logger.Error("error in Inert SMSAlert",e);
            }

            //step 5. 更新状态

            try
            {
                manager.UpdateMeteoStatus(successList, Enums.MeteoMsgStatus.FinishCreateSMS);
                manager.UpdateMeteoStatus(failList, Enums.MeteoMsgStatus.CreateSMSError);

                Logger.InfoFormat("MeteoMessage success {0}", successList.Count);
                Logger.InfoFormat("MeteoMessage fail {0}", failList.Count);
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }

        public void Exit()
        {

        }

        #endregion

        #region private method

        private string GetRelationFlightXml(List<FlightInfo> flightList)
        {
            XmlDocument doc = new XmlDocument();

            XmlElement root = doc.CreateElement("flights");

            foreach (FlightInfo info in flightList)
            {
                XmlElement flightNode = doc.CreateElement("flight");
               
                flightNode.SetAttribute("id",info.FlightInfoID);
                flightNode.SetAttribute("carrier",info.Carrier);
                flightNode.SetAttribute("flightNo", info.FlightNo);
                flightNode.SetAttribute("tailNo", info.TailNo);
                flightNode.SetAttribute("deptAirport",info.DeptAirport);
                flightNode.SetAttribute("arrAirport", info.ArrAirport);

                root.AppendChild(flightNode);
            }

            doc.AppendChild(root);

            return doc.OuterXml;
        }

        #endregion

    }
}
